pmdadb2: fix Db2 v12 MON_* column and view compatibility#2625
Conversation
📝 WalkthroughSummary by CodeRabbit
WalkthroughUpdates the Db2 PMDA in ChangesDb2 PMDA metric and runtime fixes
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
This is a followup of #2621 @natoscott I can not make |
@kurik Awesome - thanks for the investigation and fixes — the TABLESPACE_NAME -> TBSP_NAME, ACT_COMPLETED_TOTAL, SYSIBMADM.ENV_INST_INFO, and log byte-field changes all look good to me. One concern about the DEADLOCKS handling: keeping the metric returning a hardcoded zero is misleading — this way if monitoring db2.table.deadlocks we cannot distinguish "no deadlocks occurred" from "this data is not available at the table level". Better to remove it entirely. The same applies to the other lock-related columns in the MON_GET_TABLE query: LOCK_WAITS, LOCK_WAIT_TIME, and LOCK_ESCALS. If DEADLOCKS is not available per-table in Db2 v11/v12, these may have the same limitation. Could you verify whether these three columns return meaningful per-table values on your 12.1 instance, or whether they too reflect only database-wide aggregates? If they are also unavailable per-table, we should remove all four lock-related metrics (db2.table.deadlocks, db2.table.lock_waits, db2.table.lock_wait_time, db2.table.lock_escalations) from the cluster rather than stub them. The row DML counters, overflow accesses, and table scan counts would remain as the meaningful per-table metrics. |
Update SQL for Db2 12 (TBSP_NAME, ACT_COMPLETED_TOTAL, SYSIBMADM.ENV_INST_INFO, transaction log byte fields), report zero for unavailable per-table deadlocks, and only drop connections on communication failures.
To make pylint happy, the number of parameters passed to db2_refresh_instanced() has been reworked.
MON_GET_TABLE only lists tables after the monitoring connection has accessed them, so db2.table.* was always empty despite application activity. Probe user tables from SYSCAT on connect, reconnect, and before table refreshes so per-table counters are populated. Also remove the stub db2.table.deadlocks metric, which is not available in MON_GET_TABLE and was misleading when hardcoded to zero.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/pmdas/db2/pmdadb2.python`:
- Around line 1319-1320: Create a new helper method db2_exec_probe that executes
lightweight SQL probes using SELECT 1 with FETCH FIRST 1 ROW ONLY WITH UR
instead of COUNT(*), which avoids unnecessary full-table scans. The helper
should use ibm_db.exec_immediate and ibm_db.fetch_tuple to fetch at most one
row, handle exceptions with appropriate error logging, and detect connection
loss. Then replace all COUNT(*) probe calls in db2_register_user_tables and the
other affected locations (mentioned as also applying to lines 1373-1376 and
1402-1404) with calls to this new db2_exec_probe helper method.
- Around line 1248-1256: The metric definition for PM_ID(9, 2) named
'db2.instance.platform' is currently returning BLD_LEVEL data which represents a
build identifier, not platform/OS information, creating a semantic mismatch
between the metric name and its actual content. Either locate an alternative Db2
data source that provides true platform metadata and update the metric to use
that instead of BLD_LEVEL, or rename the metric from 'db2.instance.platform' to
'db2.instance.build_level' and update all references to this metric name in
downstream files including the manual page (pmdadb2.1) and the pmlogconf.summary
configuration file to reflect the new name.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository YAML (base), Repository UI (inherited), Organization UI (inherited)
Review profile: CHILL
Plan: Pro Plus
Run ID: 896620b2-151d-468b-a9f8-9fe74430bc06
📒 Files selected for processing (1)
src/pmdas/db2/pmdadb2.python
| self.PM_ID(9, 2) : ['db2.instance.platform', | ||
| pmdaMetric(self.PM_ID(9, 2), c_api.PM_TYPE_STRING, | ||
| c_api.PM_INDOM_NULL, c_api.PM_SEM_DISCRETE, noUnits), | ||
| {}, | ||
| 'Db2 instance operating platform', | ||
| 'Operating system and CPU architecture on which the Db2\n' | ||
| 'instance is running, for example "Linux/X8664".\n' | ||
| 'Source: ENV_GET_INSTANCE_INFO.PLATFORM'], | ||
| 'Db2 instance build level identifier', | ||
| 'Db2 build level string from the instance environment,\n' | ||
| 'which often encodes CPU architecture (e.g. AMD64). PLATFORM\n' | ||
| 'is not available in SYSIBMADM.ENV_INST_INFO on Db2 v12.\n' | ||
| 'Source: SYSIBMADM.ENV_INST_INFO.BLD_LEVEL'], |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major
🧩 Analysis chain
🏁 Script executed:
# First, explore repository structure
find . -name "pmdadb2.python" -o -name "pmdadb2.1" -o -name "pmlogconf.summary" | head -20Repository: performancecopilot/pcp
Length of output: 902
🏁 Script executed:
# Also check if this is a git repository to see what changed
git ls-files | grep -E "(pmdadb2|pmlogconf)" | head -20Repository: performancecopilot/pcp
Length of output: 831
🏁 Script executed:
# Get file size to determine reading strategy
wc -l src/pmdas/db2/pmdadb2.python 2>/dev/null || echo "File not found, trying alternate path"Repository: performancecopilot/pcp
Length of output: 194
🏁 Script executed:
# Read the specific lines mentioned in the review
sed -n '1240,1270p' src/pmdas/db2/pmdadb2.pythonRepository: performancecopilot/pcp
Length of output: 1667
🏁 Script executed:
# Check git history/diff for this file to understand what changed
git diff HEAD src/pmdas/db2/pmdadb2.python | head -100Repository: performancecopilot/pcp
Length of output: 160
🏁 Script executed:
# Also check if there's git log info for recent changes
git log --oneline -10 -- src/pmdas/db2/pmdadb2.pythonRepository: performancecopilot/pcp
Length of output: 237
🏁 Script executed:
# Check the downstream reference in pmdadb2.1
grep -A 5 -B 5 "db2.instance.platform" src/pmdas/db2/pmdadb2.1Repository: performancecopilot/pcp
Length of output: 160
🏁 Script executed:
# Check the downstream reference in pmlogconf.summary
grep -A 5 -B 5 "db2.instance.platform" src/pmdas/db2/pmlogconf.summaryRepository: performancecopilot/pcp
Length of output: 342
🏁 Script executed:
# Check if there are other metrics in cluster 9 to understand the context better
sed -n '1230,1260p' src/pmdas/db2/pmdadb2.pythonRepository: performancecopilot/pcp
Length of output: 1909
🏁 Script executed:
# Check the end of the file for the trailing newline requirement
tail -c 50 src/pmdas/db2/pmdadb2.python | od -cRepository: performancecopilot/pcp
Length of output: 200
🏁 Script executed:
# Search more broadly in pmdadb2.1 for platform-related documentation
cat src/pmdas/db2/pmdadb2.1 | grep -i platformRepository: performancecopilot/pcp
Length of output: 223
🏁 Script executed:
# Check the full context around cluster 9 in pmdadb2.1
sed -n '1,100p' src/pmdas/db2/pmdadb2.1 | grep -A 20 -B 5 "instance"Repository: performancecopilot/pcp
Length of output: 2389
🏁 Script executed:
# Check for trailing newline using a different approach
tail -c 10 src/pmdas/db2/pmdadb2.python | xxdRepository: performancecopilot/pcp
Length of output: 201
🏁 Script executed:
# Look at the help text more carefully - check what data is actually fetched
rg "BLD_LEVEL" src/pmdas/db2/pmdadb2.python -A 2 -B 2Repository: performancecopilot/pcp
Length of output: 611
🏁 Script executed:
# Check trailing newline requirement more carefully
tail -c 1 src/pmdas/db2/pmdadb2.python | wc -lRepository: performancecopilot/pcp
Length of output: 162
🏁 Script executed:
# Also search for what platform data would represent vs build level
web_search "Db2 PLATFORM metadata ENV_INST_INFO vs BLD_LEVEL"Repository: performancecopilot/pcp
Length of output: 208
🌐 Web query:
Db2 SYSIBMADM.ENV_INST_INFO columns platform metadata
💡 Result:
In Db2, SYSIBMADM.ENV_INST_INFO is an administrative view that returns information about the current DB2 instance [1]. However, the IBM documentation page we found does not include a column-by-column listing of SYSIBMADM.ENV_INST_INFO (at least not in the accessible “table of columns” form), so I can’t reliably enumerate every column name and its datatype/platform applicability from authoritative sources in this run. What we can ground from sources: - The view is schema SYSIBMADM and returns “current instance information” [1]. - Example usage: SELECT * FROM SYSIBMADM.ENV_INST_INFO [2]. - One specific column is INST_NAME (instance name) [3]. - Another specific column is INST_PTR_SIZE (indicates 32 vs 64-bit instance) [4]. If you want, tell me your Db2 family/product and version (LUW/Db2 Warehouse/z/OS/Db2 for i) and I can re-run a targeted search to extract the full “Information returned” column list (names + datatypes) for your exact product/version.
Citations:
- 1: https://www.ibm.com/docs/en/db2-warehouse?topic=views-env-inst-info-current-instance-information
- 2: https://data-henrik.de/2025/05/db2-system-information-sql/
- 3: https://stackoverflow.com/questions/45330968/get-db2-instance-name-using-sql
- 4: https://dba.stackexchange.com/questions/98779/how-can-i-know-my-database-version
🏁 Script executed:
# Check if there's any reference to PLATFORM in the database code
rg "PLATFORM" src/pmdas/db2/pmdadb2.pythonRepository: performancecopilot/pcp
Length of output: 241
🏁 Script executed:
# Let me also check the actual SQL query being run and what columns are available
sed -n '1200,1230p' src/pmdas/db2/pmdadb2.pythonRepository: performancecopilot/pcp
Length of output: 2105
🏁 Script executed:
# Check if there's a git diff to see the actual change (old vs new)
git show HEAD:src/pmdas/db2/pmdadb2.python 2>/dev/null | sed -n '1240,1260p' | head -40Repository: performancecopilot/pcp
Length of output: 1332
🏁 Script executed:
# Check if INST_PTR_SIZE or other columns might indicate platform
rg "INST_PTR_SIZE|INST_CODEPAGE" src/pmdas/db2/pmdadb2.pythonRepository: performancecopilot/pcp
Length of output: 160
🏁 Script executed:
# Look for any comments about the PLATFORM column availability
rg -B 5 -A 5 "PLATFORM.*not available" src/pmdas/db2/pmdadb2.pythonRepository: performancecopilot/pcp
Length of output: 160
🏁 Script executed:
# Check what the previous version had - look at git history
git log --all --oneline src/pmdas/db2/pmdadb2.python | head -5Repository: performancecopilot/pcp
Length of output: 514
🏁 Script executed:
# Get a specific commit to see what was changed
git show d4941899e:src/pmdas/db2/pmdadb2.python 2>/dev/null | sed -n '1240,1260p'Repository: performancecopilot/pcp
Length of output: 1332
🏁 Script executed:
# Search for any PLATFORM column references in commit history
git log -p --all -S "PLATFORM" -- src/pmdas/db2/pmdadb2.python 2>/dev/null | head -50Repository: performancecopilot/pcp
Length of output: 160
🏁 Script executed:
# Check the commit that added discrete instance metrics
git show 117b55d22:src/pmdas/db2/pmdadb2.python 2>/dev/null | sed -n '1240,1260p'Repository: performancecopilot/pcp
Length of output: 1464
🏁 Script executed:
# Also check what commit 9b1687674 changed (fix SQL for Db2 12.1)
git show 9b1687674:src/pmdas/db2/pmdadb2.python 2>/dev/null | sed -n '1240,1260p'Repository: performancecopilot/pcp
Length of output: 1380
🏁 Script executed:
# Check the full diff between commits to understand the evolution
git diff 117b55d22^..117b55d22 -- src/pmdas/db2/pmdadb2.python 2>/dev/null | grep -A 30 "PM_ID(9, 2)" | head -50Repository: performancecopilot/pcp
Length of output: 160
🏁 Script executed:
# Get the full metric definition from commit 117b55d22 for PM_ID(9,2)
git show 117b55d22:src/pmdas/db2/pmdadb2.python 2>/dev/null | sed -n '1230,1270p'Repository: performancecopilot/pcp
Length of output: 2639
🏁 Script executed:
# Check the diff between 117b55d22 and 9b1687674 to see what changed for this metric
git diff 117b55d22..9b1687674 -- src/pmdas/db2/pmdadb2.python 2>/dev/null | grep -A 25 -B 5 "PM_ID(9, 2)"Repository: performancecopilot/pcp
Length of output: 160
🏁 Script executed:
# Get more specific diff context showing the exact change
git show 9b1687674 -- src/pmdas/db2/pmdadb2.python 2>/dev/null | grep -A 50 "instance.platform"Repository: performancecopilot/pcp
Length of output: 160
🏁 Script executed:
# Check what the SQL query change was between versions
git diff 117b55d22..9b1687674 -- src/pmdas/db2/pmdadb2.python 2>/dev/null | grep -B 5 -A 10 "ENV_INST_INFO\|cluster_inst"Repository: performancecopilot/pcp
Length of output: 160
🏁 Script executed:
# Check the current state and the SQL query for cluster 9
grep -A 10 "cluster_inst = {" src/pmdas/db2/pmdadb2.pythonRepository: performancecopilot/pcp
Length of output: 617
🏁 Script executed:
# Check if there's a PLATFORM column in the help text in current version
sed -n '1248,1256p' src/pmdas/db2/pmdadb2.pythonRepository: performancecopilot/pcp
Length of output: 726
🏁 Script executed:
# Look for any reference to ENV_GET_INSTANCE_INFO vs SYSIBMADM.ENV_INST_INFO
rg "ENV_GET_INSTANCE_INFO|ENV_INST_INFO" src/pmdas/db2/pmdadb2.pythonRepository: performancecopilot/pcp
Length of output: 634
Do not return build level under db2.instance.platform.
The metric name still promises platform/OS information, but the value is now BLD_LEVEL, a build identifier that "often encodes" CPU architecture but is semantically distinct from platform metadata. This silently changes the public metric contract. The downstream documentation (pmdadb2.1) describes this metric as "operating platform," and pmlogconf.summary still includes it under that name. Since SYSIBMADM.ENV_INST_INFO lacks a true PLATFORM column in Db2 v12, either source platform metadata from an alternative location, or rename the metric to db2.instance.build_level and update all downstream references (docs and config files) to match.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/pmdas/db2/pmdadb2.python` around lines 1248 - 1256, The metric definition
for PM_ID(9, 2) named 'db2.instance.platform' is currently returning BLD_LEVEL
data which represents a build identifier, not platform/OS information, creating
a semantic mismatch between the metric name and its actual content. Either
locate an alternative Db2 data source that provides true platform metadata and
update the metric to use that instead of BLD_LEVEL, or rename the metric from
'db2.instance.platform' to 'db2.instance.build_level' and update all references
to this metric name in downstream files including the manual page (pmdadb2.1)
and the pmlogconf.summary configuration file to reflect the new name.
There was a problem hiding this comment.
Valid, I will fix this before merge.
There was a problem hiding this comment.
@natoscott, thanks for confirming. When you address this, the recommended path is to rename db2.instance.platform → db2.instance.build_level (updating the metric name, one-line, and long-help text in pmdadb2.python) and then sync the downstream references in src/pmdas/db2/pmdadb2.1 and src/pmdas/db2/pmlogconf.summary to match the new name. That keeps the public metric contract accurate and avoids surprising anyone who scripts against the old db2.instance.platform name expecting OS/architecture strings.
| self.known_tables[dbname] = set() | ||
| self.db2_register_user_tables(dbname) |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
# First, check file exists and get basic info
file "src/pmdas/db2/pmdadb2.python"
wc -l "src/pmdas/db2/pmdadb2.python"Repository: performancecopilot/pcp
Length of output: 232
🏁 Script executed:
# Read the key sections mentioned in the review
echo "=== Lines 1315-1325 (initial connection area) ==="
sed -n '1315,1325p' "src/pmdas/db2/pmdadb2.python"
echo -e "\n=== Lines 1370-1380 (probe query area) ==="
sed -n '1370,1380p' "src/pmdas/db2/pmdadb2.python"
echo -e "\n=== Lines 1398-1410 (reconnect area) ==="
sed -n '1398,1410p' "src/pmdas/db2/pmdadb2.python"Repository: performancecopilot/pcp
Length of output: 1755
🏁 Script executed:
# Find the db2_register_user_tables method definition
echo "=== Looking for db2_register_user_tables definition ==="
rg -n "def db2_register_user_tables" "src/pmdas/db2/pmdadb2.python" -A 30Repository: performancecopilot/pcp
Length of output: 1821
🏁 Script executed:
# Check if file ends with newline
echo "=== Checking file ending ==="
tail -c 20 "src/pmdas/db2/pmdadb2.python" | od -cRepository: performancecopilot/pcp
Length of output: 229
🏁 Script executed:
# Check trailing newline using tail and hexdump
tail -c 1 "src/pmdas/db2/pmdadb2.python" | hexdump -CRepository: performancecopilot/pcp
Length of output: 205
🌐 Web query:
Db2 COUNT(*) performance FETCH FIRST 1 ROW ONLY full table scan optimization
💡 Result:
In Db2, combining COUNT() with FETCH FIRST 1 ROW ONLY does not optimize a full table scan [1][2]. The COUNT() function is an aggregate operation that requires processing the specified rows to calculate the result [1][2]. Even when restricted by FETCH FIRST 1 ROW ONLY, the engine must still evaluate the rows to determine the count [2]. If your goal is to determine whether any rows exist in a table, using COUNT() is inefficient because it counts all matching rows (or up to the limit) rather than stopping at the first match [1][2]. Recommended alternatives for existence checks include: 1. EXISTS Predicate: Using an EXISTS clause in a subquery or conditional statement is the standard best practice [2]. The database engine stops processing as soon as it identifies a single qualifying row, significantly reducing I/O and CPU overhead [2]. Example: IF EXISTS (SELECT 1 FROM table WHERE condition) THEN... END IF; 2. Selecting a Constant: For simple existence checks, you can select a constant and fetch a single row: SELECT 1 FROM table WHERE condition FETCH FIRST 1 ROW ONLY; This approach performs better than COUNT() because the database does not need to aggregate or scan more than the first matching entry [1][2]. Performance Considerations: - FETCH FIRST 1 ROW ONLY (or OPTIMIZE FOR 1 ROW) influences the optimizer to prioritize fast access to the first row, but it does not transform an aggregate COUNT(*) into an existence check [3][4]. - Always ensure appropriate indexes exist on columns used in your WHERE clause to avoid full table scans regardless of the technique used [2]. - If you are testing existence, avoid counting rows entirely [1][2]. Use EXISTS or a limited fetch of a constant to allow the query to terminate early [2].
Citations:
- 1: https://www.ibm.com/docs/en/db2/11.1.0?topic=design-efficient-select-statements
- 2: https://mcpressonline.com/analytics-cognitive/db2/techtip-db2-for-i-optimization-strategies-part-4
- 3: https://www.ibm.com/docs/en/db2-for-zos/12.0.0?topic=statement-optimizing-retrieval-small-set-rows
- 4: https://www.techagilist.com/mainframe/db2/fetch-first-n-rows-optimize-n-rows/
🌐 Web query:
Db2 SQL WITH UR isolation level SELECT 1 query performance probe
💡 Result:
In Db2, the WITH UR (Uncommitted Read) isolation level provides a performance optimization by allowing an application to read data without acquiring most shared locks [1][2][3]. This significantly reduces lock contention and avoids "lock-wait" scenarios, making it faster than higher isolation levels like Cursor Stability (CS) [4][5]. However, the use of WITH UR comes with the trade-off of potential data inconsistency, as it allows for "dirty reads"—reading data that has been modified by other transactions but not yet committed [1][2][5]. Key considerations for a SELECT 1 query performance probe with WITH UR include: 1. Performance Characteristics: Using WITH UR for a simple SELECT 1 (or SELECT constant) query is highly performant because the database engine bypasses the overhead of acquiring and managing shared locks [2][4][3]. In a high-concurrency environment where other transactions are frequently updating data, this avoids the query stalling while waiting for those updates to complete [4]. 2. Appropriate Use Cases: WITH UR is best suited for scenarios where absolute data accuracy is not required, or where inconsistencies are acceptable [2][5]. Examples include: - Queries against rarely updated, read-only reference tables [2]. - Statistical analysis where minor inaccuracies from reading uncommitted data have negligible impact [2]. - Checking for existence when the "dirty" state is acceptable for the application logic [2]. 3. Limitations and Restrictions: - Read-only constraint: The WITH UR clause applies strictly to read-only operations (e.g., SELECT, SELECT INTO) [2][3]. If specified on a statement that Db2 determines is not read-only, it will default to Cursor Stability (CS) [6][3]. - Data Integrity: It should be avoided when transaction balance, exact accuracy, or strict data consistency is required [2]. 4. SELECT 1 Behavior: A SELECT 1 query is often used to verify the existence of a row [7]. When combined with WITH UR, it provides a lightweight existence check that is less likely to be blocked by concurrent writers, making it a common pattern in performance-sensitive applications where a "best-effort" existence check is sufficient [4][7]. For most applications, Cursor Stability (CS) remains the recommended default because it offers a balance of high concurrency and guaranteed data integrity, avoiding the risks associated with dirty reads [5].
Citations:
- 1: https://www.ibm.com/docs/en/db2/12.1.0?topic=issues-isolation-levels
- 2: https://www.ibm.com/docs/en/db2-for-zos/12.0.0?topic=option-isolation-ur
- 3: https://www.ibm.com/docs/en/db2-for-zos/12.0.0?topic=services-isolation
- 4: https://tech-champion.com/database/db2luw/optimizing-update-t-set-status-a-where-account_id-balancing-with-ur-and-data-integrity/
- 5: https://www.ibm.com/docs/en/db2-for-zos/12.0.0?topic=locks-choosing-isolation-option
- 6: https://www.ibm.com/docs/en/db2/11.5.x?topic=issues-specifying-isolation-level
- 7: https://ibmmainframes.com/about51327.html
Replace COUNT(*) probe with lightweight SELECT 1 to avoid full-table scans during table discovery.
Db2's COUNT(*) is an aggregate function that processes rows even when combined with FETCH FIRST 1 ROW ONLY, resulting in unnecessary full-table scans. This issue is compounded because db2_register_user_tables() runs on startup and reconnect, inflating metrics like ROWS_READ and TABLE_SCANS that the PMDA reports. Use SELECT 1 ... FETCH FIRST 1 ROW ONLY WITH UR instead, which stops after accessing the first row and avoids lock contention without data integrity concerns for an existence probe.
Suggested direction
if self.conns.get(dbname) is not None:
connected += 1
self.known_tables[dbname] = set()
- self.db2_register_user_tables(dbname)
@@
- probe = (
- 'SELECT COUNT(*) FROM %s.%s FETCH FIRST 1 ROW ONLY' %
- (self.db2_quote_ident(schema), self.db2_quote_ident(table)))
- if self.db2_exec(dbname, probe):
+ probe = (
+ 'SELECT 1 FROM %s.%s FETCH FIRST 1 ROW ONLY WITH UR' %
+ (self.db2_quote_ident(schema), self.db2_quote_ident(table)))
+ if self.db2_exec_probe(dbname, probe):
self.known_tables[dbname].add(key)
@@
else:
self.known_tables[dbname] = set()
- self.db2_register_user_tables(dbname)Add a lightweight helper that executes/fetches at most one row and returns True on successful execution, even for empty tables:
def db2_exec_probe(self, dbname, sql):
conn = self.db2_cursor(dbname)
try:
stmt = ibm_db.exec_immediate(conn, sql)
ibm_db.fetch_tuple(stmt)
return True
except Exception as error:
self.error("db2_exec_probe", "%s: query '%s': %s" %
(dbname, sql[:60], str(error)))
if self._db2_connection_lost(conn, error):
self.conns[dbname] = None
return FalseAlso applies to: 1373-1376, 1402-1404
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/pmdas/db2/pmdadb2.python` around lines 1319 - 1320, Create a new helper
method db2_exec_probe that executes lightweight SQL probes using SELECT 1 with
FETCH FIRST 1 ROW ONLY WITH UR instead of COUNT(*), which avoids unnecessary
full-table scans. The helper should use ibm_db.exec_immediate and
ibm_db.fetch_tuple to fetch at most one row, handle exceptions with appropriate
error logging, and detect connection loss. Then replace all COUNT(*) probe calls
in db2_register_user_tables and the other affected locations (mentioned as also
applying to lines 1373-1376 and 1402-1404) with calls to this new db2_exec_probe
helper method.
There was a problem hiding this comment.
Valid, I will fix this before merge.
There was a problem hiding this comment.
@natoscott, sounds good — thanks for the confirmation. The key points to implement when you make the fix:
- Replace
SELECT COUNT(*) FROM %s.%s FETCH FIRST 1 ROW ONLYwithSELECT 1 FROM %s.%s FETCH FIRST 1 ROW ONLY WITH UR - Add a dedicated
db2_exec_probehelper that returnsTrueeven on empty tables (a successfulexec_immediatewith no rows fetched still means the table is accessible), distinct fromdb2_execwhich returns a list of rows - Use the same probe pattern in
db2_cursor's reconnect path (db2_register_user_tables(dbname)call at Line 1404)
The WITH UR isolation level is especially appropriate here since the probe only needs to confirm table accessibility, not read consistent data.
Update SQL for Db2 12 (TBSP_NAME, ACT_COMPLETED_TOTAL, SYSIBMADM.ENV_INST_INFO, transaction log byte fields), report zero for unavailable per-table deadlocks, and only drop connections on communication failures.